package nl.project.source;

import java.util.ArrayList;

import nl.project.data.Appointment;
import nl.project.data.Enrollment;
import nl.project.data.controller.MembersDAO;

/**
 * @author Wouter de Wild en Scott Hoefnagel
 * 
 */
public class AppointmentCreator {

	ArrayList<Appointment> appointments = new ArrayList<Appointment>();
	ArrayList<Enrollment> failedEnrollments = new ArrayList<Enrollment>();
	int counter = 0;

	public AppointmentCreator() {
		createAppointment();
	}

	private void createAppointment() {
		ArrayList<Enrollment> enrollments = MembersDAO.getEnrollments();

		for (int i = 0; i < 3; i++) {
			createDay(i, "Early", enrollments);
		}
		for (int i = 0; i < 3; i++) {
			createDay(i, "Later", enrollments);
		}
		for (int i = 0; i < 3; i++) {
			createDay(i, "None", enrollments);
		}
		/*
		 * put the appointments arraylist in the database
		 */
		MembersDAO.sendFinalAppointmentList(appointments);
	}

	/**
	 * @param day
	 *            the preferred day dependent on student level
	 * @param preff
	 *            the preferred time of the evening chosen by parents
	 */
	@SuppressWarnings("rawtypes")
	private void createDay(int day, String preff, ArrayList<Enrollment> enrollments) {
		int parentID;
		int teacherID;
		boolean isTimeGood = false;

		EnrollmentLoop : for (Enrollment enrol : enrollments) {
			counter = 0;
			parentID = enrol.getParentID();
			teacherID = enrol.getTeacherID();
//			System.out.println("regel 67 - " + teacherID);

			int time = 1900;
			int numberAppo;
			if (preff.equals("Later")) {
				time = 2050;
			}
			int parentStartTime;
			ArrayList<Appointment> parentAppoList = new ArrayList<Appointment>();

			/*
			 * check if day = day (day)
			 */

			if ((Boolean) ((ArrayList) enrol.getPreferences().get(0)).get(day) == true) {
				String pref = (String) enrol.getPreferences().get(1);
				/*
				 * check preference
				 */

				if (pref.equals(preff)) {
					/*
					 * fill arraylist with all the appointments with the
					 * preference at day for one parent
					 */
					for (Appointment appo : appointments) {
						if (appo.getParentID() == parentID && appo.getPref().equals(preff)) {
							parentAppoList.add(appo);
						}
					}
					/*
					 * check if there is an appointment planned for the parent
					 */
					if (parentAppoList.size() == 0) {

						System.out.println(appointments.size() + " regel 96");
						if (appointments.size() == 0) {
							putAppointmentInList(parentID, teacherID,
									enrol.getStudentID(), time, day, preff,
									false);
							parentAppoList.clear();
							continue EnrollmentLoop;
						}

						AppointmentLoop : for (Appointment appo : appointments) {
							System.out.println("Counter: "+counter+" - AppointmentsSize: "+appointments.size());
							
							if (appo.getTeacherID() == teacherID
									&& appo.getPref().equals(preff)) {
								if (appo.getStartTime() == time) {
									time += 25;
									System.out.println("time regel 111: "
											+ time);
									if (counter < (appointments.size()-1)) {
										System.out.println("Continue");
										counter++;
										parentAppoList.clear();
										continue AppointmentLoop;
									}
									putAppointmentInList(parentID, teacherID,
											enrol.getStudentID(), time, day,
											preff, false);
									parentAppoList.clear();
									counter = 0;
									continue EnrollmentLoop;
								}

							} // else {
							// putAppointmentInList(parentID, teacherID,
							// enrol.getStudentID(), time, day, preff,
							// false);
							// parentAppoList.clear();
							// break;
							// }
						}
					}
					/*
					 * check if parent has one or more appointment
					 */
					else if (parentAppoList.size() > 0) {
						parentStartTime = parentAppoList.get(0).getStartTime();
						System.out.println("parentStartTime :"
								+ parentStartTime);
						time = parentStartTime - 50;
						if (time < 1900) {
							time = 1900;
						} else if (parentAppoList.get(0).getPref() == "Later") {
							if (time < 2050) {
								time = 2050;
							}
						}
						for (Appointment appo : appointments) {
							if (appo.getTeacherID() == teacherID
									&& appo.getPref().equals(preff)) {
								System.out.println("regel 148 - " + appo.getTeacherID());
								System.out.println("regel 149 - " + appo.getPref().equals(preff));
								isTimeGood = true;
								int teacherTime;
								int parentTime = 0;
								int count = 1;

								while (isTimeGood) {
									if (count == 1) {
										teacherTime = checkTeacherOrParentTime(
												time, appo);
										System.out
												.println("regel 158 - teacherTime:"
														+ teacherTime);
										count++;
									} else {
										teacherTime = checkTeacherOrParentTime(
												parentTime, appo);
										System.out
												.println("regel 163 - teacherTime:"
														+ teacherTime);
									}
									if (parentAppoList.size() > 1) {
										parentTime = checkTeacherOrParentTime(
												teacherTime, parentAppoList);
										System.out
												.println("regel 168 - parentTime:"
														+ parentTime);
									} else {
										parentTime = teacherTime;
										System.out
												.println("regel 171 - parentTime:"
														+ parentTime);
									}

									if (parentTime == teacherTime) {

										isTimeGood = false;
										time = teacherTime;
										System.out.println("regel 178 - Time:"
												+ time);
									}
								}
								/*
								 * check if the free time is within the allowed
								 * waiting time of 15 minutes
								 */
								if (time >= (parentStartTime - 50)
										&& time <= (parentStartTime + 50)
										&& (time <= 2175)) {
									putAppointmentInList(parentID, teacherID,
											enrol.getStudentID(), time, day,
											preff, false);
								} else if (time <= 2175) {
									putAppointmentInList(parentID, teacherID,
											enrol.getStudentID(), time, day,
											preff, true);
								} else {
									putFailedAppointment(enrol);
								}

								parentAppoList.clear();
								System.out.println(" ");
								break;
							}
						}
					}
				}
			}
		}
	}

	/**
	 * @param parentID
	 *            the parent id of the parent in the current enrollment
	 * @param teacherID
	 *            the teacher id of the teacher in the current enrollment
	 * @param studentID
	 *            the student id of the student in the current enrollment
	 * @param startTime
	 *            the start time of the newly made appointment
	 * @param date
	 *            the day on which the appointment is happening
	 * @param pref
	 *            the preference chosen by the parent "Early", "Later" or "None"
	 * @param message
	 *            boolean that points out if there needs to be a message output
	 *            that will tell the waiting time exceeds 15 minutes
	 */
	private void putAppointmentInList(int parentID, int teacherID,
			int studentID, int startTime, int date, String pref, boolean message) {
		Appointment appo = new Appointment();
		appo.setDate(date);
		appo.setParentID(parentID);
		appo.setTeacherID(teacherID);
		appo.setStartTime(startTime);
		appo.setStudentID(studentID);
		appo.setPref(pref);
		appo.setWaitingFailNotification(message);
		appointments.add(appo);
	}

	private void putFailedAppointment(Enrollment enrol) {
		failedEnrollments.add(enrol);
	}

	private int checkTeacherOrParentTime(int time, Appointment appo) {
		while (appo.getStartTime() == time) {
			time += 25;
		}

		return time;
	}

	private int checkTeacherOrParentTime(int time,
			ArrayList<Appointment> parentAppoList) {
		for (Appointment parentAppo : parentAppoList) {
			if (parentAppo.getStartTime() == time) {
				time += 25;
			}
		}

		return time;
	}
}